package 多线程;

/**
 * 使用wait/notify机制实现三个线程交替打印ABC
 * 使用synchronized关键字和Object的wait/notify方法实现线程间的通信
 */
public class PrintABCUsingWaitNotify {
    
    private int state; // 当前状态，用于控制打印顺序
    private int times; // 每个字母需要打印的次数
    private static final Object LOCK = new Object(); // 同步锁对象

    /**
     * 构造函数
     * @param times 每个字母需要打印的次数
     */
    public PrintABCUsingWaitNotify(int times){
        this.times = times;
    }

    /**
     * 打印字母的方法
     * @param name 要打印的字母
     * @param targetNum 目标状态值（0表示A，1表示B，2表示C）
     */
    private void printLetter(String name, int targetNum){
        for(int i = 0; i < times; i++){ // 循环打印指定次数
            synchronized(LOCK){ // 获取锁
                while(state % 3 != targetNum){ // 如果当前状态不是目标状态
                    try {
                        LOCK.wait(); // 等待其他线程通知
                    } catch (InterruptedException e) {
                        e.printStackTrace(); // 打印异常信息
                    }
                }
                state++; // 更新状态
                System.out.println(name); // 打印字母
                LOCK.notifyAll(); // 通知所有等待的线程
            }
        }
    }

    /**
     * 主函数：创建并启动三个线程
     * 三个线程分别负责打印A、B、C
     */
    public static void main(String[] args) {
        PrintABCUsingWaitNotify printABC = new PrintABCUsingWaitNotify(3); // 创建实例，每个字母打印3次
        
        // 创建并启动打印A的线程
        new Thread(() -> {
            printABC.printLetter("a", 0);
        }, "a").start();

        // 创建并启动打印B的线程
        new Thread(() -> {
            printABC.printLetter("b", 1);
        }, "b").start();

        // 创建并启动打印C的线程
        new Thread(() -> {
            printABC.printLetter("c", 2);
        }, "c").start();
    }
}
